/*
* Copyright (c) 2010 Michael Collins
*
* This file is part of TerraFirma.
*
* TerraFirma is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* TerraFirma is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with TerraFirma.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "timer.h"
#include "config.h"

#if defined(TF_POSIX)
    #include <sys/time.h>
#else
    #include <windows.h>
#endif
#include <cstdlib>
#include <stdio.h>

namespace engine {
    //This interface depends on system resources, and as such, has a different implementation on Mac/Linux than Windows
    timer::timer()
    {
        reset();
    }


    time timer::get_elapsed_time() const {return get_elapsed_milliseconds();}
    time timer::elapsed() const {return get_elapsed_milliseconds();}

    unsigned int timer::get_elapsed_seconds() const
    {
        return get_elapsed_milliseconds() / 1000;
    }

    time timer::get_elapsed_milliseconds() const
    {
        return system_msec() - start_time;
    }

    void timer::reset()
    {
        start_time = system_msec();
    }

    time timer::system_msec()
    {
        #ifdef TF_WINDOWS
        if(!freq)
        {
            if(!QueryPerformanceFrequency((LARGE_INTEGER*) &freq)) abort(); //WinXP and up plz!!!1
            if(freq < 1000) abort(); //We need at least millisecond granularity
            KHz = ((double)freq)/1000; //tick frequency in KHz
        }
        LARGE_INTEGER count;
        //This can have bugs on multi-processor systems? That's a problem...
        QueryPerformanceCounter(&count);
        return count / KHz;
        #else
        timeval t;
        gettimeofday(&t, NULL);
        return (t.tv_usec/1000 + (t.tv_sec * 1000));
        #endif
    }

    #ifdef TF_WINDOWS
    time timer::freq;
    double timer::KHz;
    #endif

}
